#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <syslog.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#include "log.h"


#ifndef LOG_PATH
#define LOG_PATH	"/tmp/my.log"
#endif

static const char * const log_level[] = {
	"EMERG",
	"ALERT",
	"CRITC",
	"ERROR",
	" WARN",
	" NOTI",
	" INFO",
	"DEBUG"
};

static int log_file = STDERR_FILENO;
static int log_maxsize = 4 * 1024 * 1024;
static int log_period = 1024;
static int log_buf[1024 * 1024];
static char log_path[32] = LOG_PATH;

void log_init(const char * file)
{
	if (file != NULL)
		strncpy(log_path, file, 32);

	int fd = open(log_path, O_CREAT|O_RDWR|O_APPEND|O_SYNC, 0644);
	if (fd != -1) {
		log_file = fd;
	}
}

void logging(int level, const char * fmt, ...)
{
	// ensure the log size is smaller than 
	static int _count = 0;
	if (_count > log_period && STDERR_FILENO != log_file) {
		struct stat s;
		stat(log_path, &s);
		if (s.st_size > log_maxsize) {
			char cmd[128];
			close(log_file);
			snprintf(cmd, 128, "mv %s %s.bak", log_path, log_path);
			system(cmd);
			log_init(log_path);
		}
		_count = 0;
	}
	_count++;

	level = level & 7;

	int count = 0;
	time_t t = time(NULL);
	struct tm *tm = localtime(&t);

	//offset = nstrcpy(buf, log_level[level]);
	if (tm != NULL)
		count += strftime(&log_buf[count], 32, "%Y%m%d %H:%M:%S ", tm);
	count += snprintf(&log_buf[count], 16, "[%s] ", log_level[level]);

	va_list args;

	va_start(args, fmt);
	count += vsnprintf(&log_buf[count], 1000 * 1024, fmt, args);
	va_end(args);

	if (log_buf[count-1] != '\n') {
		log_buf[count] = '\n';
		count++;
	}

	write(log_file, log_buf, count);
}
